import hashlib
import hmac
import time

from .base32Code import Base32Code

__all__ = ["OTP"]


class OTP:
    DefaultTimeStep = 60 * 15

    @staticmethod
    def generate_otp(secret):
        return OTP.generate_otp_with_time(secret, OTP.DefaultTimeStep)

    @staticmethod
    def generate_otp_with_time(secret, time_step):
        # 将 UTC 时间戳加上 8 小时（8 * 3600 秒）
        china_timestamp = time.time() + 8 * 3600

        return OTP.generate_otp_with_time_and_date(secret, time_step, china_timestamp)

    @staticmethod
    def generate_otp_with_time_and_date(secret, time_step, cal_date_time):
        data = secret.encode("utf-8")
        base32_secret = Base32Code.encode(data)
        return OTP.calc_otp(base32_secret, time_step, cal_date_time)

    @staticmethod
    def calc_otp(secret, time_step, cal_date_time):
        # 使用传入的 time_step 计算计数器
        counter = int(cal_date_time) // time_step

        # 生成 HMAC-SHA1 哈希
        counter_bytes = counter.to_bytes(8, byteorder="big")

        # 使用 Base32 解码后的密钥创建 HMAC-SHA1 实例
        hmac_hash = hmac.new(Base32Code.decode(secret), counter_bytes, hashlib.sha1).digest()

        # 使用动态截断获取最终的 6 位数字
        offset = hmac_hash[-1] & 0x0F
        binary = (
            ((hmac_hash[offset] & 0x7F) << 24)
            | ((hmac_hash[offset + 1] & 0xFF) << 16)
            | ((hmac_hash[offset + 2] & 0xFF) << 8)
            | (hmac_hash[offset + 3] & 0xFF)
        )

        # 生成 6 位数字的 OTP
        otp = binary % 1000000
        return f"{otp:06d}"


if __name__ == "__main__":
    secret = "superAdmin" + "LyAgent.ClientApi.***"
    print(OTP.generate_otp(secret))
